package com.northwest_man.refactor_tool;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SortStringXmlFile {

    private static final String regex = "(?<!-)" + Constants.STRING_ITEM_ROW_REGEX;
    // <\s*(string-array)[\s\S]+?</\s*(string-array)\s*>
    private static final String arrayRegex1 = "<\\s*(string-array)[\\s\\S]+?</\\s*(string-array)\\s*>";
    // <\s*(string-array|plurals)[\s\S]+?</\s*(string-array|plurals)\s*>
    private static final String arrayRegex2 = "<\\s*(plurals)[\\s\\S]+?</\\s*(plurals)\\s*>";
    private static Matcher matcher;

    private static void sortFile(final File file) throws IOException {

        final String fileContent = FileUtils.readFileToString(file);
        final List<KV> newList = new ArrayList<>();
        Pattern pattern = Pattern.compile(regex);
        matcher = pattern.matcher(fileContent);
        while (matcher.find()) {
            newList.add(new KV(matcher.group(1), matcher.group(2)));
        }


        Collections.sort(newList, (o1, o2) -> {
            final char[] charArr = o1.key.toCharArray();
            final char[] charArr2 = o2.key.toCharArray();
            final int size = charArr.length;
            final int size2 = charArr2.length;
            final int minSize = Math.min(size, size2);
            for (int i = 0; i < minSize; i++) {
                final char c = charArr[i];
                final char c1 = charArr2[i];
                final int sort = compareChar(c, c1);
                if (sort != 0) return sort;
            }

            return size - size2;
        });
        final StringBuilder result = new StringBuilder();
        result.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
                "<resources>");
        pattern = Pattern.compile(arrayRegex1);
        matcher = pattern.matcher(fileContent);
        while (matcher.find()) {
            result.append(matcher.group());
        }
        pattern = Pattern.compile(arrayRegex2);
        matcher = pattern.matcher(fileContent);
        while (matcher.find()) {
            result.append(matcher.group());
        }
        for (final KV item : newList) {
            result.append(" <string name=\"").append(item.key).append("\">")
                    .append(item.value).append("</string>\n");
        }
        result.append("</resources>");
        FileUtils.writeStringToFile(file, result.toString());
    }

    public static void main() throws IOException {
        final File[] dir = new File(Constants.HOME_DIR + "/Desktop/AndroidStringFiles").listFiles();
        for (final File file : dir) {
            if (!file.isDirectory()) continue;

            final File[] stringFiles = file.listFiles();
            for (final File stringFile : stringFiles) {
                if (!stringFile.isFile() || !stringFile.getName().endsWith("strings.xml")) continue;

                sortFile(stringFile);
            }
        }
    }

    private static int compareChar(char a, char b) {
        final int sort = ProcessImpl.dodo(a);
        final int sort2 = ProcessImpl.dodo(b);

        return sort - sort2;
    }

    private static abstract class ProcessImpl {

        private ProcessImpl() {
        }

        public static int dodo(int character) {
            // 获取字符所在区间排序优先级
            // 95           _
            // [48, 57]     0-9
            // [97, 122]    a-z
            // [65, 90]     A-Z
            if (character == 95) {
                return 0;
            }
            for (int i = 48, j = 1; i <= 57; i++, j++) {
                if (character == i) return j;
            }


            for (int i = 97, j = 11; i <= 122; i++, j += 2) {
                if (character == i) return j;
            }
            for (int i = 65, j = 12; i <= 90; i++, j += 2) {
                if (character == i) return j;
            }
            return -1;


        }
    }


    private static class KV {
        public final String key;
        public final String value;

        private KV(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }
}
